package com.ello.androidskeleton.ui.file

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.MediaStore
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import com.ello.androidskeleton.databinding.ActivityFileOperationBinding
import com.ello.base.common.BaseViewModel
import com.ello.base.common.BaseVmActivity
import com.ello.base.ktx.formatSize
import com.ello.base.ktx.getPathByUri
import com.ello.base.ktx.lllog
import com.ello.base.ktx.loadImage
import com.ello.base.ktx.register
import com.ello.base.ktx.toast
import com.ello.base.utils.FileChooseUtil
import com.ello.base.utils.IOUtils.readString
import com.ello.base.utils.IOUtils.writeToFile
import com.ello.base.utils.chooseFile
import com.ello.base.utils.chooseMediaByAlbum
import com.ello.base.utils.chooseMediaByFile
import com.ello.base.utils.chooseMediaByPickVisual
import com.ello.base.utils.click
import com.ello.base.utils.format
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.util.Date

/**
 *
 * 文件相关
 * @author du_xi
 * @date   2023/6/6
 */
@SuppressLint("Range")
class FileOperationActivity : BaseVmActivity<BaseViewModel, ActivityFileOperationBinding>() {


    @SuppressLint("SetTextI18n")
    override fun init(savedInstanceState: Bundle?) {

        //////////////////////////////////IO流/////////////////////////////////////
        vb.btnReadAssets.click {
            //读取assets中的 文件
            vb.tvResult.text = assets.open("file.txt").readString()
        }
        vb.btnCopyAssets.click {
            //将asset复制到cache目录文件中
            val copyResult =
                assets.open("file.txt").writeToFile(File(externalCacheDir, "file.txt"))
            vb.tvResult.text = if (copyResult) "写入成功" else "写入失败"
        }
        vb.btnReadFile.click {
            //读取文件的数据
            val file = File(externalCacheDir, "file.txt")
            if (file.exists() && file.isFile) {
                vb.tvResult.text = FileInputStream(file).readString()
            } else {
                vb.tvResult.text = "文件不存在"
            }
        }

        //////////////////////////////////选择文件/////////////////////////////////////
        //选择单个文件
        vb.btnChooseFile.click {
            chooseFile { uris ->
                showSelectFileUris(uris)
            }
        }

        //选择多个文件
        vb.btnChooseMultiFile.click {
            chooseFile(true) { uris ->
                showSelectFileUris(uris)
            }
        }


        //选择文件并读取内容
        vb.btnReadFileContent.click {
            //读取内容，不需要权限
            chooseFile { uris ->
                if (uris.isEmpty()) "未选择".toast() else {
                    contentResolver.openInputStream(uris.first())?.use { inputStream: InputStream ->
                        if (inputStream.available() > 1000) {
                            vb.tvResult.text = "文件太大：长度为${inputStream.available()}"
                        } else {
                            vb.tvResult.text = inputStream.readString()
                        }
                    }
                }
            }
        }

        //使用文件管理选择照片
        vb.btnChooseImageUseFile.click {
            chooseImage(0)
        }

        //使用相册选择照片
        vb.btnChooseFileUseAlbum.click {
            chooseImage(1)
        }

        //使用PickVisualMedia选择
        vb.btnPickImagePickVisualMedia.click {
            chooseImage(2)
        }

        //获取相册列表
        vb.btnGetAllAlbums.click {
            FileChooseUtil.loadAlbums(this, mediaType = FileChooseUtil.ImageAndVideo, { progress ->
                lllog("当前进度：$progress")
                vb.tvResult.text = "当前进度：$progress"

            }) { albumFolders->
                val stringBuilder = StringBuilder()
                albumFolders.forEach {
                    stringBuilder.append(it.folderName).append("(${it.totalNum})").append("\n")
                }
                vb.tvResult.text = stringBuilder.toString()
            }
        }
    }


    private fun chooseImage(use: Int) {
        val isMulti = vb.rbMulti.isChecked

        val mediaType = when {
            vb.rbImage.isChecked -> ActivityResultContracts.PickVisualMedia.ImageOnly
            vb.rbVideo.isChecked -> ActivityResultContracts.PickVisualMedia.VideoOnly
            else -> ActivityResultContracts.PickVisualMedia.ImageAndVideo
        }

        when (use) {
            //文件选择
            0 -> {
                chooseMediaByFile(isMulti, mediaType, ::showSelectImageUris)
            }

            1 -> {
                //选择相册
                //只能选择照片或视频，不能同时选择照片或视频
                if (vb.rbAll.isChecked) {
                    "这种情况下，只能选择照片或视频".toast()
                    return
                }
                chooseMediaByAlbum(isMulti, vb.rbVideo.isChecked, ::showSelectImageUris)
            }

            2 -> {
                chooseMediaByPickVisual(isMulti, mediaType, ::showSelectImageUris)
            }
        }
    }

    /**
     * 展示选择的文件，不需要申请任何权限
     * @param hasPermission 是否授权了读取文件权限，授权了才能获取文件真实路径等信息
     */
    private fun showSelectFileUris(uris: List<Uri>, hasPermission: Boolean = false) {
        if (uris.isEmpty()) {
            "未选择".toast()
            return
        }
        vb.ivResult.isVisible = false
        val info = StringBuilder()
        uris.forEach { uri ->

            contentResolver.query(uri, null, null, null, null)?.use { cursor: Cursor ->
                if (cursor.moveToFirst()) {
                    info.append("文件名：${cursor.getString(cursor.getColumnIndex(DocumentsContract.Document.COLUMN_DISPLAY_NAME))}\n")
                    info.append("文件大小：${cursor.getLong(cursor.getColumnIndex(DocumentsContract.Document.COLUMN_SIZE)).formatSize}\n")
                    info.append(
                        "修改时间：${
                            Date(cursor.getLong(cursor.getColumnIndex(DocumentsContract.Document.COLUMN_LAST_MODIFIED))).format()
                        }\n"
                    )
                }
            }
            if (hasPermission) {
                info.append("真实路径：").append(getPathByUri(this, uri)).append("\n")
            }
            info.append("---------------------------------------\n")
        }
        vb.tvResult.text = info
    }


    private fun showSelectImageUris(uris: List<Uri>) {
        if (uris.isEmpty()) {
            "未选择".toast()
            return
        }
        val uri = uris.first()

        vb.ivResult.isVisible = true
        vb.ivResult.loadImage(activity = this, uri = uri)
        val result = StringBuilder(uri.toString())
        contentResolver.query(uri, null, null, null, null)?.use { cursor: Cursor ->
            if (cursor.moveToFirst()) {
                val columnNames = cursor.columnNames
                for (c in columnNames) {
                    result.append("\n").append(c).append(":")
                        .append(cursor.getString(cursor.getColumnIndex(c)))
                }
            }
        }
        vb.tvResult.text = result

    }


}